package com.axapoint.opoc.service;

import java.io.StringWriter;
import java.math.BigInteger;
import java.util.ArrayList;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;

import oio.sagdok._1_0.FaktiskTidspunktType;
import oio.sagdok._1_0.OrganisationAttributListeType;
import oio.sagdok._1_0.OrganisationEgenskaberType;
import oio.sagdok._1_0.OrganisationGyldighedType;
import oio.sagdok._1_0.OrganisationLaesAttributListeType;
import oio.sagdok._1_0.OrganisationLaesEgenskaberType;
import oio.sagdok._1_0.OrganisationLaesFuldtResultatType;
import oio.sagdok._1_0.OrganisationLaesGyldighedType;
import oio.sagdok._1_0.OrganisationLaesOejebliksbilledeType;
import oio.sagdok._1_0.OrganisationLaesRelationListeType;
import oio.sagdok._1_0.OrganisationLaesResultatType;
import oio.sagdok._1_0.OrganisationLaesTilstandListeType;
import oio.sagdok._1_0.OrganisationListOutputType;
import oio.sagdok._1_0.OrganisationRegistreringType;
import oio.sagdok._1_0.OrganisationRelationListeType;
import oio.sagdok._1_0.OrganisationResultatType;
import oio.sagdok._1_0.OrganisationTilstandListeType;
import oio.sagdok._1_0.StandardreturType;
import oio.sagdok._1_0.TidspunktType;
import oio.sagdok._1_0.TilstandVirkningType;
import oio.sagdok._1_0.VirkningType;

import org.joda.time.DateTime;

import com.anasoft.os.daofusion.bitemporal.TimeUtils;
import com.axapoint.opoc.core.dao.Organization;
import com.axapoint.opoc.core.dao.OrganizationFacade;
import com.axapoint.opoc.core.dao.TestConstants;
import com.axapoint.opoc.core.dao.Organization.Bitemporal;

// Map model <-> IT&T standard
public class OrganisationMapperOio {

	public static OrganisationListOutputType hentListe(DateTime vTime, DateTime rTime, String[] uuids) throws Exception {
		OrganisationListOutputType olot = new OrganisationListOutputType();

		olot.setOrganisationListOutputStandardRetur(new StandardreturType());
		olot.getOrganisationListOutputStandardRetur().setFejlbeskedTekst("FEJL");
		olot.getOrganisationListOutputStandardRetur().setStatuskodeKode(new BigInteger("0"));
		
		olot.setOrganisationListOutputResultat(new OrganisationResultatType());

		// if uuids are null then all
		TimeUtils.setReference(rTime);
		OrganizationFacade orgFacade = new OrganizationFacade("RESTfulWS", "Demo");
		Organization[] orgz = null;
		if (uuids == null) {
			orgz = orgFacade.getAllEntities();
		} else {
			ArrayList<Organization> list = new ArrayList<Organization>();
			for (String uuid : uuids) {
				list.add(orgFacade.getEntity(uuid));
			}
		}
		
		for (Organization o : orgz) {
			OrganisationLaesResultatType olrt = new OrganisationLaesResultatType();
			olot.getOrganisationListOutputResultat().getOrganisationResultatOrganisationer().add(olrt);
				
			olrt.setOrganisationLaesResultatFuldtresultat(new OrganisationLaesFuldtResultatType());
			olrt.setOrganisationLaesResultatOejebliksbillede(new OrganisationLaesOejebliksbilledeType());
				
			// The full result is all registrations
			olrt.getOrganisationLaesResultatFuldtresultat().setOrganisationLaesFuldtResultatRegistrering(new OrganisationRegistreringType());
			olrt.getOrganisationLaesResultatFuldtresultat().getOrganisationLaesFuldtResultatRegistrering().setOrganisationRegistreringAttributter(new OrganisationAttributListeType());
			olrt.getOrganisationLaesResultatFuldtresultat().getOrganisationLaesFuldtResultatRegistrering().setOrganisationRegistreringRelationer(new OrganisationRelationListeType());
			olrt.getOrganisationLaesResultatFuldtresultat().getOrganisationLaesFuldtResultatRegistrering().setOrganisationRegistreringTilstande(new OrganisationTilstandListeType());

			for (Bitemporal bi : o.getValues().getData()) {
				OrganisationEgenskaberType attr = new OrganisationEgenskaberType();
				attr.setOrganisationNavnNavn(bi.getValue().getName());
				attr.setVirkning(new VirkningType());
				attr.getVirkning().setAktoerTekst(bi.getValue().getUserId() + "@" + bi.getValue().getUserId());
				attr.getVirkning().setCommentText("Comment tekst");
				attr.getVirkning().setFraTidspunkt(new TidspunktType());
				attr.getVirkning().getFraTidspunkt().setTidspunktFaktisk(new FaktiskTidspunktType());
				attr.getVirkning().getFraTidspunkt().getTidspunktFaktisk().setTidsstempelDatoTid(AbstractMapper.dateTimeToXMLGregorianCalendar(bi.getValidityInterval().getStart()));
				attr.getVirkning().setTilTidspunkt(new TidspunktType());
				attr.getVirkning().getTilTidspunkt().setTidspunktFaktisk(new FaktiskTidspunktType());
				attr.getVirkning().getTilTidspunkt().getTidspunktFaktisk().setTidsstempelDatoTid(AbstractMapper.dateTimeToXMLGregorianCalendar(bi.getValidityInterval().getEnd()));

				olrt.getOrganisationLaesResultatFuldtresultat().getOrganisationLaesFuldtResultatRegistrering().getOrganisationRegistreringAttributter().getOrganisationAttributListeEgenskaber().add(attr);
			}
				
			// Only this registration at validity time 
			olrt.getOrganisationLaesResultatOejebliksbillede().setUUID(o.getUuid());
			olrt.getOrganisationLaesResultatOejebliksbillede().setBrugervendtNoegleTekst("Bruger " + o.getUuid());
			olrt.getOrganisationLaesResultatOejebliksbillede().setOrganisationLaesOejebliksbilledeAttributter(new OrganisationLaesAttributListeType());
			olrt.getOrganisationLaesResultatOejebliksbillede().getOrganisationLaesOejebliksbilledeAttributter().setOrganisationLaesAttributListeEgenskaber(new OrganisationLaesEgenskaberType());			
			olrt.getOrganisationLaesResultatOejebliksbillede().getOrganisationLaesOejebliksbilledeAttributter().getOrganisationLaesAttributListeEgenskaber().setOrganisationNavnNavn(o.getValues().get(TestConstants.t3).getValue().getName());

			olrt.getOrganisationLaesResultatOejebliksbillede().setOrganisationLaesOejebliksbilledeRelationer(new OrganisationLaesRelationListeType());
			olrt.getOrganisationLaesResultatOejebliksbillede().setOrganisationLaesOejebliksbilledeTilstande(new OrganisationLaesTilstandListeType());
			olrt.getOrganisationLaesResultatOejebliksbillede().getOrganisationLaesOejebliksbilledeTilstande().setOrganisationLaesTilstandListeGyldighed(new OrganisationLaesGyldighedType());
			olrt.getOrganisationLaesResultatOejebliksbillede().getOrganisationLaesOejebliksbilledeTilstande().getOrganisationLaesTilstandListeGyldighed().setOrganisationGyldighedStatus(new BigInteger("0"));
		}		
		
		return olot;
	}
	
	public static OrganisationListOutputType hentListeDummy(DateTime vTime, DateTime rTime, String[] uuids) {
		OrganisationListOutputType olot = new OrganisationListOutputType();

		olot.setOrganisationListOutputStandardRetur(new StandardreturType());
		olot.getOrganisationListOutputStandardRetur().setFejlbeskedTekst("FEJL");
		olot.getOrganisationListOutputStandardRetur().setStatuskodeKode(new BigInteger("0"));
		
		olot.setOrganisationListOutputResultat(new OrganisationResultatType());

		OrganisationLaesResultatType olrt = new OrganisationLaesResultatType();
		olot.getOrganisationListOutputResultat().getOrganisationResultatOrganisationer().add(olrt);
			
		olrt.setOrganisationLaesResultatFuldtresultat(new OrganisationLaesFuldtResultatType());
		olrt.setOrganisationLaesResultatOejebliksbillede(new OrganisationLaesOejebliksbilledeType());
			
		// The full result is all registrations
		olrt.getOrganisationLaesResultatFuldtresultat().setOrganisationLaesFuldtResultatRegistrering(new OrganisationRegistreringType());
		olrt.getOrganisationLaesResultatFuldtresultat().getOrganisationLaesFuldtResultatRegistrering().setOrganisationRegistreringAttributter(new OrganisationAttributListeType());
		olrt.getOrganisationLaesResultatFuldtresultat().getOrganisationLaesFuldtResultatRegistrering().setOrganisationRegistreringRelationer(new OrganisationRelationListeType());
		olrt.getOrganisationLaesResultatFuldtresultat().getOrganisationLaesFuldtResultatRegistrering().setOrganisationRegistreringTilstande(new OrganisationTilstandListeType());

		
		
			
		// Only this registration at validity time 
		olrt.getOrganisationLaesResultatOejebliksbillede().setUUID("UUID");
		olrt.getOrganisationLaesResultatOejebliksbillede().setBrugervendtNoegleTekst("Bruger UUID");
		olrt.getOrganisationLaesResultatOejebliksbillede().setOrganisationLaesOejebliksbilledeAttributter(new OrganisationLaesAttributListeType());
		olrt.getOrganisationLaesResultatOejebliksbillede().getOrganisationLaesOejebliksbilledeAttributter().setOrganisationLaesAttributListeEgenskaber(new OrganisationLaesEgenskaberType());			
		olrt.getOrganisationLaesResultatOejebliksbillede().getOrganisationLaesOejebliksbilledeAttributter().getOrganisationLaesAttributListeEgenskaber().setOrganisationNavnNavn("org name");

		olrt.getOrganisationLaesResultatOejebliksbillede().setOrganisationLaesOejebliksbilledeRelationer(new OrganisationLaesRelationListeType());
		olrt.getOrganisationLaesResultatOejebliksbillede().setOrganisationLaesOejebliksbilledeTilstande(new OrganisationLaesTilstandListeType());
		olrt.getOrganisationLaesResultatOejebliksbillede().getOrganisationLaesOejebliksbilledeTilstande().setOrganisationLaesTilstandListeGyldighed(new OrganisationLaesGyldighedType());
		olrt.getOrganisationLaesResultatOejebliksbillede().getOrganisationLaesOejebliksbilledeTilstande().getOrganisationLaesTilstandListeGyldighed().setOrganisationGyldighedStatus(new BigInteger("0"));
		
		return olot;
	}
	
	public static void main(String[] args) throws Exception{
		System.out.println("---- DEBUG --- XML");

		StringWriter sw = new StringWriter();
		
		JAXBContext jaxbContext = JAXBContext.newInstance("oio.sagdok._1_0");
		OrganisationListOutputType olo = OrganisationMapperOio.hentListe(TestConstants.t2, TestConstants.rt2, null);
		JAXBElement root = new JAXBElement(new QName("urn:oio:sagdok:1.0.0","OrganisationListOutputType"), OrganisationListOutputType.class, olo);
		jaxbContext.createMarshaller().marshal( root, sw);
		
		System.out.println(sw);
		
	}
}
